package com.hzit.login.service.impl;

import com.alibaba.fastjson.JSON;
import com.hzit.auth.entity.LoginUser;
import com.hzit.auth.vo.UserVo;
import com.hzit.common.constants.CommonConstants;
import com.hzit.common.util.JwtUtil;
import com.hzit.login.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

/**
 * 类名：
 * 作者：WF
 * 功能：用户登录，完成认证
 */
@Service
public class UserServiceImpl implements IUserService {
	//0、引入认证管理器
	@Autowired
	private AuthenticationManager authenticationManager;
	@Autowired
	private StringRedisTemplate redisTemplate;

	//1. 用户登录
	@Override
	public Map<String, String> login(UserVo vo) {
		//1.1 构造一个UsernamePasswordToken
		UsernamePasswordAuthenticationToken upat = new UsernamePasswordAuthenticationToken(vo.getUsername(),vo.getPassword());
		//1.2 使用认证管理器进行认证
		Authentication authenticate = authenticationManager.authenticate(upat);
		//1.3 判断是否认证成功
		if(Objects.isNull(authenticate)){
			throw new RuntimeException("认证失败(出现了异常)！");
		}
		//1.4 到这里，证明认证成功
		//1.4.1 得到认证成功的对象
		LoginUser user = (LoginUser) authenticate.getPrincipal();
		// "hzit_user_login:abcd" ----> user
		//1.4.2 存放token到redis中
		// 生成一个uuid值
		String uuid = UUID.randomUUID().toString();
		redisTemplate.opsForValue().set(CommonConstants.AUTH_LOGIN_REDIS_PREFIX + uuid, JSON.toJSONString(user));
		//1.4.3 将uuid的值经过jwt加密传给前端
		//① 组织加密数据
		Map<String,Object> map = new HashMap();
		map.put("token",uuid);
		//② 生成token
		String token = JwtUtil.createToken(map);
		//③ 返回
		Map<String,String> resultMap  = new HashMap<>();
		resultMap.put("access_token",token);
		return resultMap;
	}
}
